package org.xx.armory.db;

import java.lang.reflect.Array;
import java.util.Collection;

/**
 * SQL查询的动态条件, 用来组合各种动态SQL语句。
 *
 * @author Haart
 */
public final class Conditions {
    private Conditions() {
        throw new UnsupportedOperationException();
    }

    /**
     * 检查指定SQL参数的值是否是{@code null}。
     *
     * @param p
     *         SQL参数。
     * @return 如果该参数的值是{@code null}则返回{@code true}, 否则返回{@code false}。
     * @see Parameter#isNull()
     */
    public static boolean isNull(Object p) {
        return p == null;
    }

    /**
     * 检查指定SQL参数的值是否<strong>不</strong>是{@code null}。
     *
     * @param p
     *         SQL参数。
     * @return 如果该参数的值不是{@code null}则返回{@code true}, 否则返回{@code false}。
     * @see Parameter#isNull()
     */
    public static boolean isNotNull(Object p) {
        return p != null;
    }

    /**
     * 判断SQL参数的值是否是{@code null}或者空白。
     *
     * @param p
     *         SQL参数。
     * @return 如果该参数的值是{@code null}或者表示长度为0的字符串或者表示长度为的数组则返回{@code true}, 否则返回{@code false}。
     * @see Parameter#isNull()
     * @see Parameter#isEmpty()
     */
    public static boolean isEmpty(Object p) {
        if (p == null) {
            return true;
        } else if (p instanceof Collection<?>) {
            return ((Collection<?>) p).size() == 0;
        } else if (p instanceof CharSequence) {
            return ((CharSequence) p).length() == 0;
        } else {
            return p.getClass().isArray() && Array.getLength(p) == 0;
        }
    }

    /**
     * 判断SQL参数的值是否<strong>不</strong>是空白。
     *
     * @param p
     *         SQL参数。
     * @return 如果该参数的值是{@code null}或者表示长度为0的字符串或者表示长度为的数组则返回{@code false}, 否则返回{@code true}。
     * @see Parameter#isEmpty()
     */
    public static boolean isNotEmpty(Object p) {
        return !isEmpty(p);
    }

    /**
     * 判断SQL参数的值是否是指定的值。
     *
     * @param p
     *         SQL参数。
     * @param v
     *         指定的值。
     * @return 如果该参数的值的字符串表达形式等于{@code v}则返回{@code true}, 否则返回{@code false}。
     */
    public static boolean equals(
            Object p,
            String v
    ) {
        return p != null && p.toString().equals(v);
    }

    /**
     * 判断SQL参数的值是否<strong>不</strong>是指定的值。
     *
     * @param p
     *         SQL参数。
     * @param v
     *         指定的值。
     * @return 如果该参数的值的字符串表达形式<strong>不</strong>等于{@code v}则返回{@code true}, 否则返回{@code false}。
     */
    public static boolean notEquals(
            Object p,
            String v
    ) {
        return p != null && !p.toString().equals(v);
    }

    /**
     * 判断SQL参数的值是否在指定的值列表中。
     *
     * @param p
     *         SQL参数。
     * @param v
     *         指定的值列表, 各个值以逗号分隔。
     * @return 如果该参数的值的字符串表达形式在列表{@code v}中则返回{@code true}, 否则返回{@code false}。
     */
    public static boolean in(
            Object p,
            String v
    ) {
        if (p == null || v == null) {
            return false;
        } else {
            final String[] array = v.split(",");
            final String vs = p.toString();
            for (final String s : array) {
                if (s.trim().equals(vs)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 判断SQL参数的值是否<strong>不</strong>在指定的值列表中。
     *
     * @param p
     *         SQL参数。
     * @param v
     *         指定的值列表, 各个值以逗号分隔。
     * @return 如果该参数的值的字符串表达形式<strong>不</strong>在列表{@code v}中则返回{@code true}, 否则返回{@code false}。
     */
    public static boolean notIn(
            Object p,
            String v
    ) {
        if (p == null || v == null) {
            return false;
        } else {
            final String[] array = v.split(",");
            final String vs = p.toString();
            for (final String s : array) {
                if (s.trim().equals(vs)) {
                    return false;
                }
            }
            return true;
        }
    }
}
